/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the EternalTech source code.

 The EternalTech source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The EternalTech source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the EternalTech source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// msgSystem.cpp - message I/O functions
//


#include "common.h"


/*
 ==================
 MSG_Init
 ==================
*/
void MSG_Init (msg_t *msg, byte *data, int size, bool allowOverflow){

	if (size > MAX_MSG_SIZE)
		Com_Error(false, "MSG_Init: %i > MAX_MSG_SIZE", size);

	msg->data = data;
	msg->size = size;
	msg->bits = size << 3;

	msg->allowOverflow = allowOverflow;
	msg->overflowed = false;

	msg->writeCount = 0;
	msg->writeBytes = 0;
	msg->writeBit = 0;

	msg->readCount = 0;
	msg->readBytes = 0;
	msg->readBit = 0;
}


/*
 ==============================================================================

 WRITING FUNCTIONS

 ==============================================================================
*/


/*
 ==================
 MSG_GetWriteState
 ==================
*/
int MSG_GetWriteState (msg_t *msg){

	return msg->writeCount;
}

/*
 ==================
 MSG_SetWriteState
 ==================
*/
void MSG_SetWriteState (msg_t *msg, int bits){

	if (bits > msg->bits)
		Com_Error(false, "MSG_SetWriteState: bad bits (%i)", bits);

	msg->overflowed = false;

	msg->writeCount = bits;
	msg->writeBytes = (bits + 7) >> 3;
	msg->writeBit = bits & 7;

	if (msg->writeBit)
		msg->data[msg->writeBytes - 1] &= BIT(msg->writeBit) - 1;
}

/*
 ==================
 MSG_ClearWriteState
 ==================
*/
void MSG_ClearWriteState (msg_t *msg){

	msg->overflowed = false;

	msg->writeCount = 0;
	msg->writeBytes = 0;
	msg->writeBit = 0;
}

/*
 ==================
 MSG_RemainingWriteBits
 ==================
*/
int MSG_RemainingWriteBits (msg_t *msg){

	if (msg->overflowed)
		return 0;

	return msg->bits - msg->writeCount;
}

/*
 ==================
 MSG_RemainingWriteBytes
 ==================
*/
int MSG_RemainingWriteBytes (msg_t *msg){

	if (msg->overflowed)
		return 0;

	return (msg->bits - msg->writeCount) >> 3;
}

/*
 ==================
 MSG_WriteAlign
 ==================
*/
void MSG_WriteAlign (msg_t *msg){

	if (msg->writeBit == 0)
		return;

	msg->writeCount += 8 - msg->writeBit;
	msg->writeBit = 0;
}

/*
 ==================
 MSG_WriteBits
 ==================
*/
void MSG_WriteBits (msg_t *msg, int value, int bits){

	int		check;
	int		put;

	if (bits == 0 || bits < -31 || bits > 32)
		Com_Error(false, "MSG_WriteBits: bad bits (%i)", bits);

	if (bits != 32){
		if (bits > 0){
			check = BIT(bits) - 1;

			if (value > check || value < 0)
				Com_Error(false, "MSG_WriteBits: value overflow (%i, %i bits)", value, bits);
		}
		else {
			check = BIT(bits - 1);

			if (value > check - 1 || value < -check)
				Com_Error(false, "MSG_WriteBits: value overflow (%i, %i bits)", value, bits);
		}
	}

	if (bits < 0)
		bits = -bits;

	// Check for overflow
	if (msg->overflowed)
		return;			// Already overflowed

	if (msg->writeCount + bits > msg->bits){
		if (!msg->allowOverflow)
			Com_Error(false, "MSG_WriteBits: overflow without allowOverflow set");

		Com_Printf(S_COLOR_YELLOW "MSG_WriteBits: overflow\n");

		msg->overflowed = true;

		return;
	}

	// Write the bits
	msg->writeCount += bits;

	while (bits){
		if (msg->writeBit == 0){
			// Write a whole byte if possible
			if (bits >= 8){
				msg->data[msg->writeBytes++] = value & 255;

				value >>= 8;
				bits -= 8;

				continue;
			}

			msg->data[msg->writeBytes++] = 0;
		}

		put = 8 - msg->writeBit;
		if (put > bits)
			put = bits;

		msg->data[msg->writeBytes - 1] |= (value & (BIT(put) - 1)) << msg->writeBit;
		msg->writeBit = (msg->writeBit + put) & 7;

		value >>= put;
		bits -= put;
	}
}

/*
 ==================
 MSG_WriteBool
 ==================
*/
void MSG_WriteBool (msg_t *msg, bool value){

	MSG_WriteBits(msg, (value != false), 1);
}

/*
 ==================
 MSG_WriteChar
 ==================
*/
void MSG_WriteChar (msg_t *msg, int value){

	MSG_WriteBits(msg, value, -8);
}

/*
 ==================
 MSG_WriteByte
 ==================
*/
void MSG_WriteByte (msg_t *msg, int value){

	MSG_WriteBits(msg, value, 8);
}

/*
 ==================
 MSG_WriteShort
 ==================
*/
void MSG_WriteShort (msg_t *msg, int value){

	MSG_WriteBits(msg, value, -16);
}

/*
 ==================
 MSG_WriteWord
 ==================
*/
void MSG_WriteWord (msg_t *msg, int value){

	MSG_WriteBits(msg, value, 16);
}

/*
 ==================
 MSG_WriteLong
 ==================
*/
void MSG_WriteLong (msg_t *msg, int value){

	MSG_WriteBits(msg, value, 32);
}

/*
 ==================
 MSG_WriteHalf
 ==================
*/
void MSG_WriteHalf (msg_t *msg, float value){

	MSG_WriteBits(msg, glqMath::FloatToHalf(value), 16);
}

/*
 ==================
 MSG_WriteFloat
 ==================
*/
void MSG_WriteFloat (msg_t *msg, float value){

	MSG_WriteBits(msg, *(int *)&value, 32);
}

/*
 ==================
 MSG_WriteAngle
 ==================
*/
void MSG_WriteAngle (msg_t *msg, float angle){

	MSG_WriteBits(msg, *(int *)&angle, 32);
}

/*
 ==================
 MSG_WriteAngle8
 ==================
*/
void MSG_WriteAngle8 (msg_t *msg, float angle){

	MSG_WriteBits(msg, ANGLE2BYTE(angle), 8);
}

/*
 ==================
 MSG_WriteAngle16
 ==================
*/
void MSG_WriteAngle16 (msg_t *msg, float angle){

	MSG_WriteBits(msg, ANGLE2SHORT(angle), 16);
}

/*
 ==================
 MSG_WriteAngles
 ==================
*/
void MSG_WriteAngles (msg_t *msg, const glqAngles &angles){

	MSG_WriteAngle(msg, angles[0]);
	MSG_WriteAngle(msg, angles[1]);
	MSG_WriteAngle(msg, angles[2]);
}

/*
 ==================
 MSG_WriteAngles8
 ==================
*/
void MSG_WriteAngles8 (msg_t *msg, const glqAngles &angles){

	MSG_WriteAngle8(msg, angles[0]);
	MSG_WriteAngle8(msg, angles[1]);
	MSG_WriteAngle8(msg, angles[2]);
}

/*
 ==================
 MSG_WriteAngles16
 ==================
*/
void MSG_WriteAngles16 (msg_t *msg, const glqAngles &angles){

	MSG_WriteAngle16(msg, angles[0]);
	MSG_WriteAngle16(msg, angles[1]);
	MSG_WriteAngle16(msg, angles[2]);
}

/*
 ==================
 MSG_WriteVec2
 ==================
*/
void MSG_WriteVec2 (msg_t *msg, const glqVec2 &vec){

	MSG_WriteFloat(msg, vec[0]);
	MSG_WriteFloat(msg, vec[1]);
}

/*
 ==================
 MSG_WriteVec3
 ==================
*/
void MSG_WriteVec3 (msg_t *msg, const glqVec3 &vec){

	MSG_WriteFloat(msg, vec[0]);
	MSG_WriteFloat(msg, vec[1]);
	MSG_WriteFloat(msg, vec[2]);
}

/*
 ==================
 MSG_WriteVec4
 ==================
*/
void MSG_WriteVec4 (msg_t *msg, const glqVec4 &vec){

	MSG_WriteFloat(msg, vec[0]);
	MSG_WriteFloat(msg, vec[1]);
	MSG_WriteFloat(msg, vec[2]);
	MSG_WriteFloat(msg, vec[3]);
}

/*
 ==================
 MSG_WriteVec5
 ==================
*/
void MSG_WriteVec5 (msg_t *msg, const glqVec5 &vec){

	MSG_WriteFloat(msg, vec[0]);
	MSG_WriteFloat(msg, vec[1]);
	MSG_WriteFloat(msg, vec[2]);
	MSG_WriteFloat(msg, vec[3]);
	MSG_WriteFloat(msg, vec[4]);
}

/*
 ==================
 MSG_WriteNormal
 ==================
*/
void MSG_WriteNormal (msg_t *msg, const glqVec3 &normal){

	byte	bytes[2];

	glqMath::NormalToBytes(normal, bytes);

	MSG_WriteBits(msg, bytes[0], 8);
	MSG_WriteBits(msg, bytes[1], 8);
}

/*
 ==================
 MSG_WriteString
 ==================
*/
void MSG_WriteString (msg_t *msg, const char *string){

	int		c;

	while (*string){
		c = *(const byte *)string++;

		MSG_WriteBits(msg, c, 8);
	}

	MSG_WriteBits(msg, 0, 8);
}

/*
 ==================
 MSG_WriteData
 ==================
*/
void MSG_WriteData (msg_t *msg, const void *data, int size){

	int		i;

	// See if we can write optimized
	if (!msg->overflowed && msg->writeBit == 0 && size <= ((msg->bits - msg->writeCount) >> 3)){
		Mem_Copy(msg->data + msg->writeBytes, data, size);

		msg->writeCount += size << 3;
		msg->writeBytes += size;

		return;
	}

	// Write one byte at a time
	for (i = 0; i < size; i++)
		MSG_WriteBits(msg, ((const byte *)data)[i], 8);
}

/*
 ==================
 MSG_WriteDeltaBits
 ==================
*/
void MSG_WriteDeltaBits (msg_t *msg, int oldValue, int newValue, int bits){

	if (oldValue == newValue){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, newValue, bits);
}

/*
 ==================
 MSG_WriteDeltaChar
 ==================
*/
void MSG_WriteDeltaChar (msg_t *msg, int oldValue, int newValue){

	if (oldValue == newValue){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, newValue, -8);
}

/*
 ==================
 MSG_WriteDeltaByte
 ==================
*/
void MSG_WriteDeltaByte (msg_t *msg, int oldValue, int newValue){

	if (oldValue == newValue){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, newValue, 8);
}

/*
 ==================
 MSG_WriteDeltaShort
 ==================
*/
void MSG_WriteDeltaShort (msg_t *msg, int oldValue, int newValue){

	if (oldValue == newValue){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, newValue, -16);
}

/*
 ==================
 MSG_WriteDeltaWord
 ==================
*/
void MSG_WriteDeltaWord (msg_t *msg, int oldValue, int newValue){

	if (oldValue == newValue){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, newValue, 16);
}

/*
 ==================
 MSG_WriteDeltaLong
 ==================
*/
void MSG_WriteDeltaLong (msg_t *msg, int oldValue, int newValue){

	if (oldValue == newValue){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, newValue, 32);
}

/*
 ==================
 MSG_WriteDeltaHalf
 ==================
*/
void MSG_WriteDeltaHalf (msg_t *msg, float oldValue, float newValue){

	if (oldValue == newValue){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, glqMath::FloatToHalf(newValue), 16);
}

/*
 ==================
 MSG_WriteDeltaFloat
 ==================
*/
void MSG_WriteDeltaFloat (msg_t *msg, float oldValue, float newValue){

	if (oldValue == newValue){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, *(int *)&newValue, 32);
}

/*
 ==================
 MSG_WriteDeltaAngle
 ==================
*/
void MSG_WriteDeltaAngle (msg_t *msg, float oldAngle, float newAngle){

	if (oldAngle == newAngle){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, *(int *)&newAngle, 32);
}

/*
 ==================
 MSG_WriteDeltaAngle8
 ==================
*/
void MSG_WriteDeltaAngle8 (msg_t *msg, float oldAngle, float newAngle){

	if (oldAngle == newAngle){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, ANGLE2BYTE(newAngle), 8);
}

/*
 ==================
 MSG_WriteDeltaAngle16
 ==================
*/
void MSG_WriteDeltaAngle16 (msg_t *msg, float oldAngle, float newAngle){

	if (oldAngle == newAngle){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, ANGLE2SHORT(newAngle), 16);
}

/*
 ==================
 MSG_WriteDeltaAngles
 ==================
*/
void MSG_WriteDeltaAngles (msg_t *msg, const glqAngles &oldAngles, const glqAngles &newAngles){

	MSG_WriteDeltaAngle(msg, oldAngles[0], newAngles[0]);
	MSG_WriteDeltaAngle(msg, oldAngles[1], newAngles[1]);
	MSG_WriteDeltaAngle(msg, oldAngles[2], newAngles[2]);
}

/*
 ==================
 MSG_WriteDeltaAngles8
 ==================
*/
void MSG_WriteDeltaAngles8 (msg_t *msg, const glqAngles &oldAngles, const glqAngles &newAngles){

	MSG_WriteDeltaAngle8(msg, oldAngles[0], newAngles[0]);
	MSG_WriteDeltaAngle8(msg, oldAngles[1], newAngles[1]);
	MSG_WriteDeltaAngle8(msg, oldAngles[2], newAngles[2]);
}

/*
 ==================
 MSG_WriteDeltaAngles16
 ==================
*/
void MSG_WriteDeltaAngles16 (msg_t *msg, const glqAngles &oldAngles, const glqAngles &newAngles){

	MSG_WriteDeltaAngle16(msg, oldAngles[0], newAngles[0]);
	MSG_WriteDeltaAngle16(msg, oldAngles[1], newAngles[1]);
	MSG_WriteDeltaAngle16(msg, oldAngles[2], newAngles[2]);
}

/*
 ==================
 MSG_WriteDeltaVec2
 ==================
*/
void MSG_WriteDeltaVec2 (msg_t *msg, const glqVec2 &oldVec, const glqVec2 &newVec){

	MSG_WriteDeltaFloat(msg, oldVec[0], newVec[0]);
	MSG_WriteDeltaFloat(msg, oldVec[1], newVec[1]);
}

/*
 ==================
 MSG_WriteDeltaVec3
 ==================
*/
void MSG_WriteDeltaVec3 (msg_t *msg, const glqVec3 &oldVec, const glqVec3 &newVec){

	MSG_WriteDeltaFloat(msg, oldVec[0], newVec[0]);
	MSG_WriteDeltaFloat(msg, oldVec[1], newVec[1]);
	MSG_WriteDeltaFloat(msg, oldVec[2], newVec[2]);
}

/*
 ==================
 MSG_WriteDeltaVec4
 ==================
*/
void MSG_WriteDeltaVec4 (msg_t *msg, const glqVec4 &oldVec, const glqVec4 &newVec){

	MSG_WriteDeltaFloat(msg, oldVec[0], newVec[0]);
	MSG_WriteDeltaFloat(msg, oldVec[1], newVec[1]);
	MSG_WriteDeltaFloat(msg, oldVec[2], newVec[2]);
	MSG_WriteDeltaFloat(msg, oldVec[3], newVec[3]);
}

/*
 ==================
 MSG_WriteDeltaVec5
 ==================
*/
void MSG_WriteDeltaVec5 (msg_t *msg, const glqVec5 &oldVec, const glqVec5 &newVec){

	MSG_WriteDeltaFloat(msg, oldVec[0], newVec[0]);
	MSG_WriteDeltaFloat(msg, oldVec[1], newVec[1]);
	MSG_WriteDeltaFloat(msg, oldVec[2], newVec[2]);
	MSG_WriteDeltaFloat(msg, oldVec[3], newVec[3]);
	MSG_WriteDeltaFloat(msg, oldVec[4], newVec[4]);
}

/*
 ==================
 MSG_WriteDeltaNormal
 ==================
*/
void MSG_WriteDeltaNormal (msg_t *msg, const glqVec3 &oldNormal, const glqVec3 &newNormal){

	byte	bytes[2];

	if (oldNormal == newNormal){
		MSG_WriteBits(msg, 0, 1);
		return;
	}

	glqMath::NormalToBytes(newNormal, bytes);

	MSG_WriteBits(msg, 1, 1);
	MSG_WriteBits(msg, bytes[0], 8);
	MSG_WriteBits(msg, bytes[1], 8);
}


/*
 ==============================================================================

 READING FUNCTIONS

 ==============================================================================
*/


/*
 ==================
 MSG_GetReadState
 ==================
*/
int MSG_GetReadState (msg_t *msg){

	return msg->readCount;
}

/*
 ==================
 MSG_SetReadState
 ==================
*/
void MSG_SetReadState (msg_t *msg, int bits){

	if (bits > msg->writeCount)
		Com_Error(false, "MSG_SetReadState: bad bits (%i)", bits);

	msg->readCount = bits;
	msg->readBytes = (bits + 7) >> 3;
	msg->readBit = bits & 7;
}

/*
 ==================
 MSG_ClearReadState
 ==================
*/
void MSG_ClearReadState (msg_t *msg){

	msg->readCount = 0;
	msg->readBytes = 0;
	msg->readBit = 0;
}

/*
 ==================
 MSG_RemainingReadBits
 ==================
*/
int MSG_RemainingReadBits (msg_t *msg){

	if (msg->readCount > msg->writeCount)
		return 0;

	return msg->writeCount - msg->readCount;
}

/*
 ==================
 MSG_RemainingReadBytes
 ==================
*/
int MSG_RemainingReadBytes (msg_t *msg){

	if (msg->readCount > msg->writeCount)
		return 0;

	return (msg->writeCount - msg->readCount) >> 3;
}

/*
 ==================
 MSG_ReadAlign
 ==================
*/
void MSG_ReadAlign (msg_t *msg){

	if (msg->readBit == 0)
		return;

	msg->readCount += 8 - msg->readBit;
	msg->readBit = 0;
}

/*
 ==================
 MSG_ReadBits
 ==================
*/
int MSG_ReadBits (msg_t *msg, int bits){

	bool	sign = false;
	int		count = 0;
	int		value = 0;
	int		get;

	if (bits == 0 || bits < -31 || bits > 32)
		Com_Error(false, "MSG_ReadBits: bad bits (%i)", bits);

	if (bits < 0){
		bits = -bits;

		sign = true;
	}

	// Check for overflow
	if (msg->readCount > msg->writeCount)
		return -1;		// Already overflowed

	if (msg->readCount + bits > msg->writeCount){
		msg->readCount = msg->readCount + bits;
		msg->readBytes = (msg->readCount + 7) >> 3;
		msg->readBit = msg->readCount & 7;

		return -1;
	}

	// Read the bits
	msg->readCount += bits;

	while (count < bits){
		if (msg->readBit == 0){
			// Read a whole byte if possible
			if (bits - count >= 8){
				value |= msg->data[msg->readBytes++] << count;

				count += 8;

				continue;
			}

			msg->readBytes++;
		}

		get = 8 - msg->readBit;
		if (get > bits - count)
			get = bits - count;

		value |= ((msg->data[msg->readBytes - 1] >> msg->readBit) & (BIT(get) - 1)) << count;
		msg->readBit = (msg->readBit + get) & 7;

		count += get;
	}

	if (sign){
		if (value & BIT(bits - 1))
			value |= -1 ^ (BIT(bits) - 1);
	}

	return value;
}

/*
 ==================
 MSG_ReadBool
 ==================
*/
bool MSG_ReadBool (msg_t *msg){

	return (bool)MSG_ReadBits(msg, 1);
}

/*
 ==================
 MSG_ReadChar
 ==================
*/
int MSG_ReadChar (msg_t *msg){

	return (char)MSG_ReadBits(msg, -8);
}

/*
 ==================
 MSG_ReadByte
 ==================
*/
int MSG_ReadByte (msg_t *msg){

	return (byte)MSG_ReadBits(msg, 8);
}

/*
 ==================
 MSG_ReadShort
 ==================
*/
int MSG_ReadShort (msg_t *msg){

	return (short)MSG_ReadBits(msg, -16);
}

/*
 ==================
 MSG_ReadWord
 ==================
*/
int MSG_ReadWord (msg_t *msg){

	return (word)MSG_ReadBits(msg, 16);
}

/*
 ==================
 MSG_ReadLong
 ==================
*/
int MSG_ReadLong (msg_t *msg){

	return MSG_ReadBits(msg, 32);
}

/*
 ==================
 MSG_ReadHalf
 ==================
*/
float MSG_ReadHalf (msg_t *msg){

	half	value;

	value = (half)MSG_ReadBits(msg, 16);

	return glqMath::HalfToFloat(value);
}

/*
 ==================
 MSG_ReadFloat
 ==================
*/
float MSG_ReadFloat (msg_t *msg){

	float	value;

	*(int *)&value = MSG_ReadBits(msg, 32);

	return value;
}

/*
 ==================
 MSG_ReadAngle
 ==================
*/
float MSG_ReadAngle (msg_t *msg){

	float	angle;

	*(int *)&angle = MSG_ReadBits(msg, 32);

	return angle;
}

/*
 ==================
 MSG_ReadAngle8
 ==================
*/
float MSG_ReadAngle8 (msg_t *msg){

	int		angle;

	angle = (byte)MSG_ReadBits(msg, 8);

	return BYTE2ANGLE(angle);
}

/*
 ==================
 MSG_ReadAngle16
 ==================
*/
float MSG_ReadAngle16 (msg_t *msg){

	int		angle;

	angle = (short)MSG_ReadBits(msg, 16);

	return SHORT2ANGLE(angle);
}

/*
 ==================
 MSG_ReadAngles
 ==================
*/
glqAngles MSG_ReadAngles (msg_t *msg){

	glqAngles	angles;

	angles[0] = MSG_ReadAngle(msg);
	angles[1] = MSG_ReadAngle(msg);
	angles[2] = MSG_ReadAngle(msg);

	return angles;
}

/*
 ==================
 MSG_ReadAngles8
 ==================
*/
glqAngles MSG_ReadAngles8 (msg_t *msg){

	glqAngles	angles;

	angles[0] = MSG_ReadAngle8(msg);
	angles[1] = MSG_ReadAngle8(msg);
	angles[2] = MSG_ReadAngle8(msg);

	return angles;
}

/*
 ==================
 MSG_ReadAngles16
 ==================
*/
glqAngles MSG_ReadAngles16 (msg_t *msg){

	glqAngles	angles;

	angles[0] = MSG_ReadAngle16(msg);
	angles[1] = MSG_ReadAngle16(msg);
	angles[2] = MSG_ReadAngle16(msg);

	return angles;
}

/*
 ==================
 MSG_ReadVec2
 ==================
*/
glqVec2 MSG_ReadVec2 (msg_t *msg){

	glqVec2	vec;

	vec[0] = MSG_ReadFloat(msg);
	vec[1] = MSG_ReadFloat(msg);

	return vec;
}

/*
 ==================
 MSG_ReadVec3
 ==================
*/
glqVec3 MSG_ReadVec3 (msg_t *msg){

	glqVec3	vec;

	vec[0] = MSG_ReadFloat(msg);
	vec[1] = MSG_ReadFloat(msg);
	vec[2] = MSG_ReadFloat(msg);

	return vec;
}

/*
 ==================
 MSG_ReadVec4
 ==================
*/
glqVec4 MSG_ReadVec4 (msg_t *msg){

	glqVec4	vec;

	vec[0] = MSG_ReadFloat(msg);
	vec[1] = MSG_ReadFloat(msg);
	vec[2] = MSG_ReadFloat(msg);
	vec[3] = MSG_ReadFloat(msg);

	return vec;
}

/*
 ==================
 MSG_ReadVec5
 ==================
*/
glqVec5 MSG_ReadVec5 (msg_t *msg){

	glqVec5	vec;

	vec[0] = MSG_ReadFloat(msg);
	vec[1] = MSG_ReadFloat(msg);
	vec[2] = MSG_ReadFloat(msg);
	vec[3] = MSG_ReadFloat(msg);
	vec[4] = MSG_ReadFloat(msg);

	return vec;
}

/*
 ==================
 MSG_ReadNormal
 ==================
*/
glqVec3 MSG_ReadNormal (msg_t *msg){

	glqVec3	normal;
	byte	bytes[2];

	bytes[0] = (byte)MSG_ReadBits(msg, 8);
	bytes[1] = (byte)MSG_ReadBits(msg, 8);

	glqMath::BytesToNormal(bytes, normal);

	return normal;
}

/*
 ==================
 MSG_ReadString
 ==================
*/
int MSG_ReadString (msg_t *msg, char *string, int maxLength){

	int		c, len = 0;

	while (1){
		c = (byte)MSG_ReadBits(msg, 8);

		if (c == 0)
			break;

		// Translate all fmt spec to avoid crash bugs
		if (c == '%')
			c = '.';

		if (len < maxLength - 1)
			string[len++] = c;
	}

	string[len] = 0;

	return len;
}

/*
 ==================
 MSG_ReadData
 ==================
*/
int MSG_ReadData (msg_t *msg, void *data, int size){

	int		count = msg->readCount;
	int		i;

	// See if we can read optimized
	if (msg->readBit == 0 && size <= ((msg->writeCount - msg->readCount) >> 3)){
		Mem_Copy(data, msg->data + msg->readBytes, size);

		msg->readCount += size << 3;
		msg->readBytes += size;

		return size;
	}

	// Read one byte at a time
	for (i = 0; i < size; i++)
		((byte *)data)[i] = (byte)MSG_ReadBits(msg, 8);

	if (msg->readCount > msg->writeCount)
		return (msg->writeCount - count) >> 3;

	return size;
}

/*
 ==================
 MSG_ReadDeltaBits
 ==================
*/
int MSG_ReadDeltaBits (msg_t *msg, int oldValue, int bits){

	if (!MSG_ReadBits(msg, 1))
		return oldValue;

	return MSG_ReadBits(msg, bits);
}

/*
 ==================
 MSG_ReadDeltaChar
 ==================
*/
int MSG_ReadDeltaChar (msg_t *msg, int oldValue){

	if (!MSG_ReadBits(msg, 1))
		return (char)oldValue;

	return (char)MSG_ReadBits(msg, -8);
}

/*
 ==================
 MSG_ReadDeltaByte
 ==================
*/
int MSG_ReadDeltaByte (msg_t *msg, int oldValue){

	if (!MSG_ReadBits(msg, 1))
		return (byte)oldValue;

	return (byte)MSG_ReadBits(msg, 8);
}

/*
 ==================
 MSG_ReadDeltaShort
 ==================
*/
int MSG_ReadDeltaShort (msg_t *msg, int oldValue){

	if (!MSG_ReadBits(msg, 1))
		return (short)oldValue;

	return (short)MSG_ReadBits(msg, -16);
}

/*
 ==================
 MSG_ReadDeltaWord
 ==================
*/
int MSG_ReadDeltaWord (msg_t *msg, int oldValue){

	if (!MSG_ReadBits(msg, 1))
		return (word)oldValue;

	return (word)MSG_ReadBits(msg, 16);
}

/*
 ==================
 MSG_ReadDeltaLong
 ==================
*/
int MSG_ReadDeltaLong (msg_t *msg, int oldValue){

	if (!MSG_ReadBits(msg, 1))
		return oldValue;

	return MSG_ReadBits(msg, 32);
}

/*
 ==================
 MSG_ReadDeltaHalf
 ==================
*/
float MSG_ReadDeltaHalf (msg_t *msg, float oldValue){

	half	newValue;

	if (!MSG_ReadBits(msg, 1))
		return oldValue;

	newValue = (half)MSG_ReadBits(msg, 16);

	return glqMath::HalfToFloat(newValue);
}

/*
 ==================
 MSG_ReadDeltaFloat
 ==================
*/
float MSG_ReadDeltaFloat (msg_t *msg, float oldValue){

	float	newValue;

	if (!MSG_ReadBits(msg, 1))
		return oldValue;

	*(int *)&newValue = MSG_ReadBits(msg, 32);

	return newValue;
}

/*
 ==================
 MSG_ReadDeltaAngle
 ==================
*/
float MSG_ReadDeltaAngle (msg_t *msg, float oldAngle){

	float	newAngle;

	if (!MSG_ReadBits(msg, 1))
		return oldAngle;

	*(int *)&newAngle = MSG_ReadBits(msg, 32);

	return newAngle;
}

/*
 ==================
 MSG_ReadDeltaAngle8
 ==================
*/
float MSG_ReadDeltaAngle8 (msg_t *msg, float oldAngle){

	int		newAngle;

	if (!MSG_ReadBits(msg, 1))
		return oldAngle;

	newAngle = (byte)MSG_ReadBits(msg, 8);

	return BYTE2ANGLE(newAngle);
}

/*
 ==================
 MSG_ReadDeltaAngle16
 ==================
*/
float MSG_ReadDeltaAngle16 (msg_t *msg, float oldAngle){

	int		newAngle;

	if (!MSG_ReadBits(msg, 1))
		return oldAngle;

	newAngle = (short)MSG_ReadBits(msg, 16);

	return SHORT2ANGLE(newAngle);
}

/*
 ==================
 MSG_ReadDeltaAngles
 ==================
*/
glqAngles MSG_ReadDeltaAngles (msg_t *msg, const glqAngles &oldAngles){

	glqAngles	newAngles;

	newAngles[0] = MSG_ReadDeltaAngle(msg, oldAngles[0]);
	newAngles[1] = MSG_ReadDeltaAngle(msg, oldAngles[1]);
	newAngles[2] = MSG_ReadDeltaAngle(msg, oldAngles[2]);

	return newAngles;
}

/*
 ==================
 MSG_ReadDeltaAngles8
 ==================
*/
glqAngles MSG_ReadDeltaAngles8 (msg_t *msg, const glqAngles &oldAngles){

	glqAngles	newAngles;

	newAngles[0] = MSG_ReadDeltaAngle8(msg, oldAngles[0]);
	newAngles[1] = MSG_ReadDeltaAngle8(msg, oldAngles[1]);
	newAngles[2] = MSG_ReadDeltaAngle8(msg, oldAngles[2]);

	return newAngles;
}

/*
 ==================
 MSG_ReadDeltaAngles16
 ==================
*/
glqAngles MSG_ReadDeltaAngles16 (msg_t *msg, const glqAngles &oldAngles){

	glqAngles	newAngles;

	newAngles[0] = MSG_ReadDeltaAngle16(msg, oldAngles[0]);
	newAngles[1] = MSG_ReadDeltaAngle16(msg, oldAngles[1]);
	newAngles[2] = MSG_ReadDeltaAngle16(msg, oldAngles[2]);

	return newAngles;
}

/*
 ==================
 MSG_ReadDeltaVec2
 ==================
*/
glqVec2 MSG_ReadDeltaVec2 (msg_t *msg, const glqVec2 &oldVec){

	glqVec2	newVec;

	newVec[0] = MSG_ReadDeltaFloat(msg, oldVec[0]);
	newVec[1] = MSG_ReadDeltaFloat(msg, oldVec[1]);

	return newVec;
}

/*
 ==================
 MSG_ReadDeltaVec3
 ==================
*/
glqVec3 MSG_ReadDeltaVec3 (msg_t *msg, const glqVec3 &oldVec){

	glqVec3	newVec;

	newVec[0] = MSG_ReadDeltaFloat(msg, oldVec[0]);
	newVec[1] = MSG_ReadDeltaFloat(msg, oldVec[1]);
	newVec[2] = MSG_ReadDeltaFloat(msg, oldVec[2]);

	return newVec;
}

/*
 ==================
 MSG_ReadDeltaVec4
 ==================
*/
glqVec4 MSG_ReadDeltaVec4 (msg_t *msg, const glqVec4 &oldVec){

	glqVec4	newVec;

	newVec[0] = MSG_ReadDeltaFloat(msg, oldVec[0]);
	newVec[1] = MSG_ReadDeltaFloat(msg, oldVec[1]);
	newVec[2] = MSG_ReadDeltaFloat(msg, oldVec[2]);
	newVec[3] = MSG_ReadDeltaFloat(msg, oldVec[3]);

	return newVec;
}

/*
 ==================
 MSG_ReadDeltaVec5
 ==================
*/
glqVec5 MSG_ReadDeltaVec5 (msg_t *msg, const glqVec5 &oldVec){

	glqVec5	newVec;

	newVec[0] = MSG_ReadDeltaFloat(msg, oldVec[0]);
	newVec[1] = MSG_ReadDeltaFloat(msg, oldVec[1]);
	newVec[2] = MSG_ReadDeltaFloat(msg, oldVec[2]);
	newVec[3] = MSG_ReadDeltaFloat(msg, oldVec[3]);
	newVec[4] = MSG_ReadDeltaFloat(msg, oldVec[4]);

	return newVec;
}

/*
 ==================
 MSG_ReadDeltaNormal
 ==================
*/
glqVec3 MSG_ReadDeltaNormal (msg_t *msg, const glqVec3 &oldNormal){

	glqVec3	newNormal;
	byte	bytes[2];

	if (!MSG_ReadBits(msg, 1))
		return oldNormal;

	bytes[0] = (byte)MSG_ReadBits(msg, 8);
	bytes[1] = (byte)MSG_ReadBits(msg, 8);

	glqMath::BytesToNormal(bytes, newNormal);

	return newNormal;
}